package com.appbee.media.client.presenter;

import java.util.Date;
import java.util.List;

import javax.inject.Inject;
import javax.inject.Provider;

import com.appbee.core.client.ui.IMessageView;
import com.appbee.core.client.upload.ErrorListener;
import com.appbee.core.client.upload.ErrorTarget;
import com.appbee.core.client.upload.File;
import com.appbee.core.client.upload.FileReadResult;
import com.appbee.core.client.upload.FileReader;
import com.appbee.core.client.upload.LoadListener;
import com.appbee.core.client.upload.ProgressEvent;
import com.appbee.core.client.upload.ProgressListener;
import com.appbee.core.client.upload.UploadErrorHandler;
import com.appbee.core.client.upload.UploadHandler;
import com.appbee.core.client.upload.XMLHttpRequest;
import com.appbee.core.client.upload.XMLHttpRequestUpload;
import com.appbee.media.shared.MediaServiceRequest;
import com.google.gwt.activity.shared.AbstractActivity;
import com.google.gwt.event.shared.EventBus;
import com.google.web.bindery.requestfactory.shared.Receiver;
import com.google.gwt.user.client.ui.AcceptsOneWidget;
import com.google.gwt.user.client.ui.IsWidget;
import com.google.gwt.xhr.client.ReadyStateChangeHandler;

public class MediaUploadActivity extends AbstractActivity
{
	public interface View extends IsWidget
	{

		public void setPresenter(MediaUploadActivity presenter);
		
		public IMessageView getMessageView();

		public ImageView addImage(String fileName,int size);
		
	}
	
	public interface ImageView
	{
		void setImageData(String data);
		
		void setLoadedProcent(int p);

		void setError(String error);

		void showMedia(String mediaId);
		
	}
	
	private static final String suportedMimeTypes = "image/jpeg,image/png,image/gif";
	
	private View view;
	private Provider<MediaServiceRequest> mediaServiceProvider;

	
	@Inject
	public MediaUploadActivity(View view,Provider<MediaServiceRequest> mediaServiceProvider)
	{
		super();
		this.view = view;
		this.mediaServiceProvider = mediaServiceProvider;
		view.setPresenter(this);
	}


	@Override
	public void start(AcceptsOneWidget panel, EventBus eventBus)
	{
		panel.setWidget(view);
	}

	
	public void upload(final File[] files)
	{
		if(files!=null && files.length>0)
		{
			mediaServiceProvider.get().createUploadUrl(files.length).fire(new Receiver<List<String>>()
			{

				@Override
				public void onSuccess(List<String> response)
				{
					for (int i = 0; i < files.length; i++)
					{
						//showFile(files[i]);
						sendFile(files[i], response.get(i));
					}
				}
				
			});			
		}
	}

	protected void showFile(final File file)
	{
		if(suportedMimeTypes.indexOf(file.getType())==-1) return;
		FileReader reader = FileReader.create();
		final ImageView image = view.addImage(file.getName()+" "+file.getType(),file.getSize());
		reader.setLoadListener(new LoadListener()
		{
			
			@Override
			public void onLoad(ProgressEvent event)
			{
				FileReadResult eventTarget = (FileReadResult)event.getEventTarget();
				image.setImageData(eventTarget.getResult());
				image.setLoadedProcent(100);
			}
		});
		reader.setProgressListener(new ProgressListener()
		{
			
			@Override
			public void onProgress(ProgressEvent event)
			{
				int p = Math.round(event.getLoaded()*100/event.getTotal());
				if(p<=100)
				{
					image.setLoadedProcent(p);
				}
			}
		});
		reader.setErrorListener(new ErrorListener()
		{
			
			@Override
			public void onError(ProgressEvent event)
			{
				ErrorTarget eventTarget = (ErrorTarget)event.getEventTarget();
				image.setError("Villa: "+eventTarget.getError().getCode());
			}
		});
		reader.readAsDataURL(file);
	}
	
	private void sendFile(final File file,String uploadUrl)
	{
		if(suportedMimeTypes.indexOf(file.getType())==-1) return;
		FileReader reader = FileReader.create();
		final ImageView image = view.addImage(file.getName(),file.getSize());
	
		final XMLHttpRequest req = XMLHttpRequest.create();
		XMLHttpRequestUpload upload = req.getUpload();
		upload.addEventListener("progress", new UploadHandler()
		{
			@Override
			public void onUpload(ProgressEvent e)
			{
				//logPanel.setInnerHTML("Loaded: "+e.getLoaded()+" total: "+e.getTotal());
				int p = Math.round(e.getLoaded()*100/e.getTotal());
				if(p<100)
				{
					image.setLoadedProcent(p);
				}
			}
		},  false);
		upload.addErrorHandler(new UploadErrorHandler()
		{
			
			@Override
			public void onError(String error)
			{
				image.setError(error);
			}
		},false);
		req.setOnReadyStateChange(new ReadyStateChangeHandler()
		{
			
			@Override
			public void onReadyStateChange(com.google.gwt.xhr.client.XMLHttpRequest xhr)
			{
				if(xhr.getReadyState()==4)
				{
					image.showMedia(xhr.getResponseText());
				}
			}
		});
		//req.overrideMimeType("text/plain; charset=x-user-defined-binary");
		req.open("POST", uploadUrl);
		
		reader.setLoadListener(new LoadListener()
		{
			
			@Override
			public void onLoad(ProgressEvent event)
			{
				FileReadResult eventTarget = (FileReadResult)event.getEventTarget();
				String boundary = "------"+new Date().getTime();
				req.setRequestHeader("Content-Type", "multipart/form-data; boundary="+boundary);
				StringBuffer sb = createUploadData(file,eventTarget.getResult(), boundary);
				
				req.sendAsBinary(sb.toString());
			}
		});
		reader.readAsBinaryString(file);
		
	}


	private StringBuffer createUploadData(File file,String fileContent, String boundary)
	{
		StringBuffer sb = new StringBuffer();
		String dashdash = "--";
		String newLine = "\r\n";
		sb.append("Content-Type: multipart/form-data; boundary=");
		sb.append(boundary);
		sb.append(newLine);
		sb.append(dashdash);
		sb.append(boundary);
		sb.append(newLine);
		sb.append("Content-Disposition: form-data; name=\"myFile\"; filename=\"");
		sb.append(file.getName());
		sb.append("\"");
		sb.append(newLine);
		sb.append("Content-Type: image/jpeg");
		sb.append(newLine);
		sb.append(newLine);
		sb.append(fileContent);
		sb.append(newLine);
		sb.append(dashdash);
		sb.append(boundary);
		sb.append(dashdash);
		sb.append(newLine);
		return sb;
	}
	
}
